package de.slothsoft.bookmaker.parse;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import de.slothsoft.bookmaker.ProgressMonitor;
import de.slothsoft.bookmaker.pdf.PdfRequest;

public class OverviewParser implements WebsiteParser {

    private final ParserCreator creator;
    private final List<String> chapterUrls;

    private StreamProvider streamProvider = new DefaultStreamProvider();

    public OverviewParser(ParserCreator creator, List<String> chapterUrls) {
        this.creator = creator;
        this.chapterUrls = chapterUrls;
    }

    @Override
    public PdfRequest[] parse(ProgressMonitor monitor) throws IOException {
        List<ImageXPathParser> parsers = createParsers();
        updateMonitor(monitor, parsers);
        return parse(monitor, parsers);
    }

    public List<ImageXPathParser> createParsers() throws IOException {
        List<ImageXPathParser> parsers = new ArrayList<>(this.chapterUrls.size());
        for (String chapterUrl : this.chapterUrls) {
            try (InputStream input = this.streamProvider.createStream(chapterUrl)) {
                parsers.add(this.creator.createParser(input, chapterUrl));
            }
        }
        return parsers;
    }

    protected void updateMonitor(ProgressMonitor monitor, List<ImageXPathParser> parsers) {
        int count = 0;
        for (ImageXPathParser parser : parsers) {
            count += parser.getPageUrls().size();
        }
        monitor.setStep(0.5 / count);
    }

    public PdfRequest[] parse(ProgressMonitor monitor, List<ImageXPathParser> parsers) throws IOException {
        List<PdfRequest> requests = new ArrayList<>(this.chapterUrls.size());
        for (ImageXPathParser parser : parsers) {
            requests.addAll(Arrays.asList(parser.parse(monitor)));
        }
        return requests.toArray(new PdfRequest[requests.size()]);
    }

    public List<String> getChapterUrls() {
        return this.chapterUrls;
    }

    public StreamProvider getStreamProvider() {
        return this.streamProvider;
    }

    public void setStreamProvider(StreamProvider streamProvider) {
        this.streamProvider = streamProvider;
    }

    /**
     * 
     */

    public static interface ParserCreator {

        ImageXPathParser createParser(InputStream input, String chapterUrl) throws IOException;
    }

}
